package com.alibaba.wallstreet.uitls;
import java.io.*;

import org.bouncycastle.openpgp.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PGPFileProcessor {
    private static Logger logger                  = LoggerFactory.getLogger(PGPFileProcessor.class);
    
    private String passphrase;
    private String publicKeyFileName;
    private String secretKeyFileName;
    private String inputFileName;
    private String outputFileName;
    private boolean asciiArmored = false;
    private boolean integrityCheck = true;

    public boolean encrypt() throws Exception {
        FileOutputStream out = null;
        FileInputStream keyIn = null;
        try{
             out = new FileOutputStream(outputFileName);
             keyIn = new FileInputStream(publicKeyFileName);
             PGPUtil.encryptFile(out, inputFileName, PGPUtil.readPublicKey(keyIn), asciiArmored, integrityCheck);
        }
        finally{
            if (out!=null) {
                try {
                    out.close();          
                } catch (Exception e) {
                    logger.error("Close stream err", e);
                }
            }
            if(keyIn!=null){
                try {
                    keyIn.close();
                } catch (Exception e) {
                    logger.error("Close stream err", e);
                }
            }
        }   
        return true;
    }
    
    
    public boolean decrypt() throws Exception {
        FileInputStream in = null;
        FileInputStream keyIn = null;
        FileOutputStream out = null;
        try {
             in = new FileInputStream(inputFileName);
             keyIn = new FileInputStream(secretKeyFileName);
             out = new FileOutputStream(outputFileName);
             PGPUtil.decryptFile(in, out, keyIn, passphrase.toCharArray());  
        }finally{
            if (in!=null) {    
                try {
                    in.close();          
                } catch (Exception e) {
                    logger.error("Close stream err", e);
                }
            }
            if (out!=null) {    
                try {
                    out.close();          
                } catch (Exception e) {
                    logger.error("Close stream err", e);
                }
            }
            if (keyIn!=null) {    
                try {
                    keyIn.close();          
                } catch (Exception e) {
                    logger.error("Close stream err", e);
                }
            }
        }
        return true;
    }
    
    
    public boolean decryptVerifyStreamKey() throws Exception {
        FileInputStream in = null;
        FileInputStream publicKeyIn = null;
        FileInputStream secretKeyIn = null;
        try {
            
             in = new FileInputStream(inputFileName);
             publicKeyIn = new FileInputStream(publicKeyFileName);
             secretKeyIn = new FileInputStream(secretKeyFileName);
             PGPUtil.decryptVerifyFile(in, outputFileName, outputFileName+"_temp", secretKeyIn, passphrase, publicKeyIn);
        } finally{
            if (in!=null) {    
                try {
                    in.close();          
                } catch (Exception e) {
                    logger.error("Close stream err", e);
                }
            }
            if (publicKeyIn!=null) {    
                try {
                    publicKeyIn.close();          
                } catch (Exception e) {
                    logger.error("Close stream err", e);
                }
            }
            if (secretKeyIn!=null) {    
                try {
                    secretKeyIn.close();          
                } catch (Exception e) {
                    logger.error("Close stream err", e);
                }
            }
        }
        return true;
    }
    

    public boolean signEncrypt() throws Exception {
        FileOutputStream out = null;
        FileInputStream publicKeyIn = null;
        FileInputStream secretKeyIn = null;
        try {
            out = new FileOutputStream(outputFileName);
            publicKeyIn = new FileInputStream(publicKeyFileName);
            secretKeyIn = new FileInputStream(secretKeyFileName);
            
            PGPPublicKey publicKey = PGPUtil.readPublicKey(publicKeyIn);
            PGPSecretKey secretKey = PGPUtil.readSecretKey(secretKeyIn);
            
            PGPUtil.signEncryptFile(
                                    out,
                                    this.getInputFileName(),
                                    publicKey,
                                    secretKey,
                                    this.getPassphrase(),
                                    this.isAsciiArmored(),
                                    this.isIntegrityCheck() );
        }finally{     
            if (out!=null) {    
                try {
                    out.close();          
                } catch (Exception e) {
                    logger.error("Close stream err", e);
                }
            }
            if (publicKeyIn!=null) {    
                try {
                    publicKeyIn.close();          
                } catch (Exception e) {
                    logger.error("Close stream err", e);
                }
            }
            if (secretKeyIn!=null) {    
                try {
                    secretKeyIn.close();          
                } catch (Exception e) {
                    logger.error("Close stream err", e);
                }
            }
        }
        return true;
    }

    
    public boolean decryptVerify() throws Exception {
        FileInputStream in = null;
        FileInputStream publicKeyIn = null;
        FileInputStream secretKeyIn = null;
        try {
            in = new FileInputStream(inputFileName);
            publicKeyIn = new FileInputStream(publicKeyFileName);
            secretKeyIn = new FileInputStream(secretKeyFileName);
            
            PGPPublicKey publicKey = PGPUtil.readPublicKey(publicKeyIn);
            PGPSecretKey secretKey = PGPUtil.readSecretKey(secretKeyIn);
            
            PGPUtil.decryptVerifyFile(in, outputFileName, outputFileName+"_temp", secretKey, passphrase, publicKey);
        }finally{
            if (in!=null) {    
                try {
                    in.close();          
                } catch (Exception e) {
                    logger.error("Close stream err", e);
                }
            }
            if (publicKeyIn!=null) {    
                try {
                    publicKeyIn.close();          
                } catch (Exception e) {
                    logger.error("Close stream err", e);
                }
            }
            if (secretKeyIn!=null) {    
                try {
                    secretKeyIn.close();          
                } catch (Exception e) {
                    logger.error("Close stream err", e);
                }
            }
        }
        return true;
    }

    
    public boolean isAsciiArmored() {
            return asciiArmored;
    }

    public void setAsciiArmored(boolean asciiArmored) {
            this.asciiArmored = asciiArmored;
    }

    public boolean isIntegrityCheck() {
            return integrityCheck;
    }

    public void setIntegrityCheck(boolean integrityCheck) {
            this.integrityCheck = integrityCheck;
    }

    public String getPassphrase() {
            return passphrase;
    }

    public void setPassphrase(String passphrase) {
            this.passphrase = passphrase;
    }

    public String getPublicKeyFileName() {
            return publicKeyFileName;
    }

    public void setPublicKeyFileName(String publicKeyFileName) {
            this.publicKeyFileName = publicKeyFileName;
    }
    
    public String getSecretKeyFileName() {
        return secretKeyFileName;
    }

    
    public void setSecretKeyFileName(String secretKeyFileName) {
        this.secretKeyFileName = secretKeyFileName;
    }

    public String getInputFileName() {
            return inputFileName;
    }

    public void setInputFileName(String inputFileName) {
            this.inputFileName = inputFileName;
    }

    public String getOutputFileName() {
            return outputFileName;
    }

    public void setOutputFileName(String outputFileName) {
            this.outputFileName = outputFileName;
    }

}